﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lidgren.Network;
using Lidgren.Network.Xna;
using Microsoft.Xna.Framework;
using SharedLib.Engine;

namespace SharedLib.Network.Server
{
    public class ServerSender
    {
        Server server;
        NetServer netserver;
        NetOutgoingMessage outmsg;

        public ServerSender(NetServer nets, Server srv)
        {
            server = srv;
            netserver = nets;
        }

        public void SendInitialUpdate(ServerPlayer player)
        {
            outmsg = netserver.CreateMessage();
            outmsg.Write((byte)SharedLib.Constants.PacketType.PlayerInitialUpdate);
            player.WriteData(outmsg);
            netserver.SendMessage(outmsg, player.NetConn, NetDeliveryMethod.ReliableOrdered);
        }

        public void SendPlayerChunk(ServerPlayer player)
        {
            outmsg = netserver.CreateMessage();
            outmsg.Write((byte)SharedLib.Constants.PacketType.ChunkTransfer);

            server.GameWorld.WriteWorld(player, outmsg);
            server.EntitiesManager.writeEntities(player, outmsg);

            

            netserver.SendMessage(outmsg, player.NetConn, NetDeliveryMethod.ReliableOrdered);

        }

        public void SendCurrentWorld(ServerPlayer player)
        {
            outmsg = netserver.CreateMessage();
            outmsg.Write((byte)SharedLib.Constants.PacketType.WorldMapTransfer);

            
           

            outmsg.Write(server.EntitiesManager.EntitiesList.Count-1);
            for (int i = 0; i < server.EntitiesManager.EntitiesList.Count; i++)
            {

                Entity p = server.EntitiesManager.EntitiesList.ElementAt(i).Value;
                if (p.ID != player.ID)
                {
                    p.WriteData(outmsg);
                }

            }


            netserver.SendMessage(outmsg, player.NetConn, NetDeliveryMethod.ReliableOrdered);
        }

        public void SendEntityJoined(Entity entity)
        {
            


            List<ServerPlayer> players = new List<ServerPlayer>();
            for (int x = entity.getChunkPosition().X - 1; x < entity.getChunkPosition().X + 2; x++)
            {
                for (int y = entity.getChunkPosition().Y - 1; y < entity.getChunkPosition().Y + 2; y++)
                {
                    ServerChunk currentChunk = server.GameWorld.Chunks.Where(c => c.X == x && c.Y == y).FirstOrDefault();
                    if (currentChunk != null)
                    {
                        foreach (ServerPlayer item in currentChunk.Entities.Where(e => e.GetType() == typeof(ServerPlayer)).ToList())
                        {
                            if (entity.ID != item.ID)
                            {
                                if (!players.Contains(item))
                                    players.Add(item);

                            }
                        }
                    }
                }
            }
            foreach (var item in players)
            {
                outmsg = netserver.CreateMessage();
                outmsg.Write((byte)SharedLib.Constants.PacketType.EntityJoin);

                entity.WriteData(outmsg);
                netserver.SendMessage(outmsg, item.NetConn, NetDeliveryMethod.ReliableOrdered);
            }

        }

        public void SendEntityLeft(Entity entity)
        {

            List<ServerPlayer> players = new List<ServerPlayer>();
            for (int x = entity.getChunkPosition().X - 1; x < entity.getChunkPosition().X + 2; x++)
            {
                for (int y = entity.getChunkPosition().Y - 1; y < entity.getChunkPosition().Y + 2; y++)
                {
                    ServerChunk currentChunk = server.GameWorld.Chunks.Where(c => c.X == x && c.Y == y).FirstOrDefault();
                    if (currentChunk != null)
                    {
                        foreach (ServerPlayer item in currentChunk.Entities.Where(e => e.GetType() == typeof(ServerPlayer)).ToList())
                        {
                            if (entity.ID != item.ID)
                            {
                                if (!players.Contains(item))
                                    players.Add(item);

                            }
                        }
                    }
                }
            }
            foreach (var item in players)
            {
                outmsg = netserver.CreateMessage();
                outmsg.Write((byte)SharedLib.Constants.PacketType.EntityLeft);
                outmsg.Write(entity.ID);
                netserver.SendMessage(outmsg, item.NetConn, NetDeliveryMethod.ReliableOrdered);
            }
        }

        public void SendMovementUpdate(Entity entity)
        {
            

            List<ServerPlayer> players = new List<ServerPlayer>();
            for (int x = entity.getChunkPosition().X - 1; x < entity.getChunkPosition().X + 2; x++)
            {
                for (int y = entity.getChunkPosition().Y - 1; y < entity.getChunkPosition().Y + 2; y++)
                {
                    ServerChunk currentChunk = server.GameWorld.Chunks.Where(c => c.X == x && c.Y == y).FirstOrDefault();
                    if (currentChunk != null)
                    {
                        foreach (ServerPlayer item in currentChunk.Entities.Where(e => e.GetType() == typeof(ServerPlayer)).ToList())
                        {
                            if (entity.ID != item.ID)
                            {
                                if(!players.Contains(item))
                                    players.Add(item);
                               // 
                            }
                        }
                    }
                }
            }
            foreach (var item in players)
            {
                outmsg = netserver.CreateMessage();
                outmsg.Write((byte)SharedLib.Constants.PacketType.EntityMovementUpdate);
                outmsg.Write(entity.ID);
                outmsg.Write(entity.Position);
                netserver.SendMessage(outmsg, item.NetConn, NetDeliveryMethod.ReliableOrdered);
            }

        }

        public void SendRotationUpdate(Entity entity)
        {
            



            List<ServerPlayer> players = new List<ServerPlayer>();
            for (int x = entity.getChunkPosition().X - 1; x < entity.getChunkPosition().X + 2; x++)
            {
                for (int y = entity.getChunkPosition().Y - 1; y < entity.getChunkPosition().Y + 2; y++)
                {
                    ServerChunk currentChunk = server.GameWorld.Chunks.Where(c => c.X == x && c.Y == y).FirstOrDefault();
                    if (currentChunk != null)
                    {
                        foreach (ServerPlayer item in currentChunk.Entities.Where(e => e.GetType() == typeof(ServerPlayer)).ToList())
                        {
                            if (entity.ID != item.ID)
                            {
                                if (!players.Contains(item))
                                    players.Add(item);
                                
                            }
                        }
                    }
                }
            }
            foreach (var item in players)
            {
                outmsg = netserver.CreateMessage();
                outmsg.Write((byte)SharedLib.Constants.PacketType.EntityRotationUpdate);
                outmsg.Write(entity.ID);
                outmsg.Write(entity.Rotation);
                netserver.SendMessage(outmsg, item.NetConn, NetDeliveryMethod.ReliableOrdered);
            }

        }

       
    }
}
